package factory;

import Annotation.Destroy;
import Annotation.Initialization;
import Annotation.Scope;
import entity.User;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分原型和单例实例化类
 */
public class NewBean {
    //单例容器
    private static Map<String,Object> map=new HashMap<String,Object>();

    //通过Class对象获取实例 简直是clazz.getName()
    public static <T> T getBean(Class<?> clazz)throws Exception{
        //setUserMap(clazz);
        Object o = setMapBean(clazz);
        return (T) o;
    }

    //标识容器
    //private static Map<String, User> userMap=new HashMap<String,User>();
   /* //把类信息存放到标识容器
    private static void setUserMap(Class<?> clazz){
        User user = new User();
        Scope annotation = clazz.getAnnotation(Scope.class);
        user.setId(clazz.getSimpleName());
        user.setClazz(clazz);
        user.setScope(clazz.getAnnotation(Scope.class).prototype());
        //看有没有销毁方法 或者初始化方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(int i=0;i<declaredMethods.length;i++){
            user.setDestroy(declaredMethods[i].isAnnotationPresent(Destroy.class));
            user.setInitialization(declaredMethods[i].isAnnotationPresent(Initialization.class));
        }
        userMap.put(user.getId(),user);
    }*/


    //把单例的存放到map集合
    private static <T> T setMapBean(Class<?> clazz) throws Exception{
        Object o=null;
        Scope annotation = clazz.getAnnotation(Scope.class);
        //如果为单例
        if(annotation.prototype().equals("singleton")) {
            //如果第一次加载
            if (map.get(clazz.getSimpleName()) == null) {
                map.put(clazz.getSimpleName(), clazz.newInstance());
                o=map.get(clazz.getSimpleName());
            }else {
                o=map.get(clazz.getSimpleName());
            }
        }else{
           o=clazz.newInstance();
        }
        return (T) o;
    }

    /**
     * 初始化
     */
    public static void initialization(Class<?> aClass) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for(int i=0;i<declaredMethods.length;i++) {
            if(declaredMethods[i].isAnnotationPresent(Initialization.class)){
                declaredMethods[i].invoke(aClass.newInstance());
            }
        }
    }

    /**
     *销毁
     */
    private static void destroyMethod() throws InvocationTargetException, IllegalAccessException {
        for(String key:map.keySet()){
            Object o = map.get(key);
            Class<?> aClass = o.getClass();
            Method[] declaredMethods = aClass.getDeclaredMethods();
            for(int i=0;i<declaredMethods.length;i++) {
                if(declaredMethods[i].isAnnotationPresent(Destroy.class)){
                    declaredMethods[i].invoke(o);
                }
            }
        }
    }

    /**
     *关闭map集合
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static void close() throws InvocationTargetException, IllegalAccessException {
        destroyMethod();
        map.clear();
    }
}
